package com.imooc.business.core.executor.collect;

import com.imooc.business.builder.CollectSqlBuilder;
import com.imooc.business.context.DataContext;
import com.imooc.business.domain.Rule;
import com.imooc.business.domain.Storage;
import com.imooc.infra.repository.jdbc.DynamicJdbcRepository;
import com.imooc.infra.repository.jdbc.params.StandardSqlParam;
import com.imooc.module.collect.enums.DimensionEnum;
import com.imooc.module.collect.enums.PeriodEnum;
import com.imooc.module.collect.request.ParamsRequest;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author Tim
 * @Description: 高维度指标采集，基于基础维度做指标汇聚
 * @Version 1.0
 */
@Component(value = "defaultCollectProcess")
public class HighCollectProcess extends AbstractCollectProcess{
    private final DynamicJdbcRepository dynamicJdbcRepository;
    public HighCollectProcess(DynamicJdbcRepository dynamicJdbcRepository) {
        this.dynamicJdbcRepository = dynamicJdbcRepository;
    }
    @Override
    public void collect(DataContext context) {
        DataContext.CacheModel cacheModel = context.getCacheModel();
        Rule rule = cacheModel.getRule();
        if (!checkCollect(rule)) {
            return;
        }
        Map<String, Object> params = context.buildCollectParams();
        List<Map<String, Object>> results = context.buildCollectResult();

        //格式化我们开始-结束时间
        ParamsRequest request = context.getRequest();
        fomatTimeParams(params, request.getStartTime(), request.getEndTime(), StandardSqlParam.DATE_PATTERN);

        Storage storage = rule.getStorage();
        DimensionEnum dimension = cacheModel.getDimension();
        List<String> sqlList = CollectSqlBuilder.buildSql(rule, cacheModel.getDimension(), cacheModel.getPeriod());
        sqlList.parallelStream().forEach(querySql -> {
            List<Map<String, Object>> queryResult = dynamicJdbcRepository.queryMapList(querySql, storage.getDataSource(), params);
            combineResult(dimension, results, queryResult);
        });
        //讲所有的结果集加入到DataContext上下文
        cacheModel.getResults().addAll(filter(results, rule.getCollects()));
    }

    /**
     * 把当前查询到的结果，合并到初始化结果(results)
     * @param dimension
     * @param results
     * @param queryResult
     */
    private void combineResult(DimensionEnum dimension, List<Map<String, Object>> results, List<Map<String, Object>> queryResult) {
        if (CollectionUtils.isEmpty(queryResult)) {
            return;
        }
        results.forEach(m -> queryResult.stream().
                filter(m2 -> Objects.equals(m.get(StandardSqlParam.getDimensionColumn(dimension)),
                        m2.get(StandardSqlParam.getDimensionColumn(dimension)))).
                forEach(m::putAll));
    }

    @Override
    public PeriodEnum supportPeriod() {
        return null;
    }

    @Override
    public DimensionEnum supportDimension() {
        return null;
    }
}
